package com.cardone.platform.common.dao;

import com.cardone.context.Attributes;
import com.cardone.context.CodeException;
import com.cardone.context.ContextHolder;
import com.cardone.context.function.Execution1Function;
import com.cardone.persistent.support.JdbcTemplateSupport;
import com.cardone.persistent.support.SimpleJdbcDao;
import com.cardone.platform.common.dto.EntityCodeDto;
import com.google.common.collect.Maps;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;

import java.util.Map;
import java.util.UUID;

/**
 * 实体编号
 *
 * @author yaohaitao
 */
@Getter
@Setter
@Slf4j
public class EntityCodeJdbcDao extends SimpleJdbcDao<EntityCodeDto> implements EntityCodeDao {
    public EntityCodeJdbcDao() {
        super(EntityCodeDao.SqlIds.ROOT);
    }

    @Override
    protected boolean isBlankById(EntityCodeDto dto) {
        return StringUtils.isBlank(dto.getId());
    }

    @Override
    protected void setId(EntityCodeDto dto) {
        dto.setId(UUID.randomUUID().toString());
    }

    @Override
    public String generateCode(final String id, final String typeCode, final Execution1Function<String, String> function, final Map<String, Object> parameters) {
        String newId = StringUtils.defaultIfBlank(id, "Common");

        final String insertByNotExistsCodeSql = SqlIds.insertByNotExistsCodeFor.id() + newId;

        final String readMaxCodeByCodeSql = SqlIds.readMaxCodeByCodeFor.id() + newId;

        final Map<String, Object> newParameters = Maps.newHashMap();

        if (MapUtils.isNotEmpty(parameters)) {
            newParameters.putAll(parameters);
        } else {
            newParameters.put("codePrefix", typeCode + "_");
        }

        newParameters.put(Attributes.typeCode.name(), typeCode);

        String code;

        int reCount = 0;

        while (true) {
            code = ContextHolder.getBean(JdbcTemplateSupport.class).read(String.class, readMaxCodeByCodeSql, newParameters);

            newParameters.put(Attributes.id.name(), UUID.randomUUID().toString());
            newParameters.put(Attributes.code.name(), code);
            newParameters.put(Attributes.typeCode.name(), typeCode);

            if (function != null) {
                code = function.execution(code);
            }

            final int insertCount = ContextHolder.getBean(JdbcTemplateSupport.class).update(insertByNotExistsCodeSql, newParameters);

            if (insertCount > 0) {
                break;
            }

            reCount++;

            if (reCount > 100) {
                throw new CodeException("重试了100次也没有获取到不重复的编号");
            }
        }

        return code;
    }
}
